#pragma once
#include <Windows.h>

#include <string>
#include <vector>
#include <TlHelp32.h>
using namespace std;

namespace memory_tool {

	class memory_manager {
	public:
		HWND mem_hwnd = nullptr;
		HANDLE mem_handle = nullptr;
		int pid;
		std::uintptr_t client_dll = 0x0;
		std::uintptr_t engine_dll = 0x0;
		
		memory_manager(std::string_view name) {
			bind_process(name);
			bind_modules("client.dll",client_dll);
			bind_modules("engine.dll", engine_dll);

		}

		void bind_process(std::string_view name);
	
		void bind_modules(std::string_view name, uintptr_t& dll);
		inline HANDLE GetProcesshandle(_In_ DWORD dwDesiredAccess,_In_ BOOL bInheritHandle,_In_ DWORD dwProcessId);


	template<typename T>
	T read(uintptr_t address) {
		T t;
		if (!ReadProcessMemory(mem_handle, reinterpret_cast<LPVOID> (address), &t, sizeof T, nullptr)) {
			Sleep(1000);
		}

		return t;
	}

	template<typename T>
	void read_list(uintptr_t address,T* t,size_t count) {
		if (t == NULL)exit(0);
		if (!ReadProcessMemory(mem_handle, reinterpret_cast<LPVOID> (address), t, count * (sizeof T), nullptr)) {
			Sleep(1000);
		}

	}

	template<typename T>
	void read_chain(uintptr_t address, vector<uintptr_t> vec, T& out) {
		for (int i = 0; i < vec.size(); i++) {
			if (i + 1 == vec.size()) {
				out = read<T>(address+vec[i]);
			}
			else {
				address = read<uintptr_t>(address + vec[i]);
			}

		}
		
	}
	};

}
